package com.qiangesoft.im.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qiangesoft.im.auth.UserUtil;
import com.qiangesoft.im.entity.ImGroup;
import com.qiangesoft.im.entity.ImGroupUser;
import com.qiangesoft.im.exception.ServiceException;
import com.qiangesoft.im.mapper.ImGroupUserMapper;
import com.qiangesoft.im.pojo.dto.ImGroupUserDTO;
import com.qiangesoft.im.pojo.vo.SysUserVo;
import com.qiangesoft.im.service.IImGroupService;
import com.qiangesoft.im.service.IImGroupUserService;
import com.qiangesoft.im.service.ISysUserService;
import com.qiangesoft.im.util.IdSplitUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 群成员 服务实现类
 * </p>
 *
 * @author qiangesoft
 * @date 2024-02-07
 */
@Service
public class ImGroupUserServiceImpl extends ServiceImpl<ImGroupUserMapper, ImGroupUser> implements IImGroupUserService {
    @Autowired
    private ISysUserService sysUserService;
    @Lazy
    @Autowired
    private IImGroupService groupService;

    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void addGroupUser(ImGroupUserDTO groupUserDTO) {
        Long groupId = groupUserDTO.getGroupId();
        ImGroup group = groupService.validateGroup(groupId);
        if (group.getDelFlag()) {
            throw new ServiceException("群组已解散！");
        }

        Long userId = UserUtil.getUserId();
        List<Long> managerIdList = IdSplitUtil.strToList(group.getManager());
        if (group.getMaster().equals(userId)) {
            throw new ServiceException("无添加好友权限！");
        } else {
            if (!managerIdList.contains(userId)) {
                throw new ServiceException("无添加好友权限！");
            }
        }
        List<Long> memberIdList = groupUserDTO.getMemberIdList();
        if (memberIdList.contains(userId)) {
            throw new ServiceException("你是群主，不可添加！");
        }

        LambdaQueryWrapper<ImGroupUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ImGroupUser::getGroupId, groupId)
                .eq(ImGroupUser::getDelFlag, false);
        List<Long> existMemberIdList = baseMapper.selectList(queryWrapper).stream().map(ImGroupUser::getUserId).collect(Collectors.toList());

        List<Long> notExistMemberIdList = memberIdList.stream().filter(e -> !existMemberIdList.contains(e)).collect(Collectors.toList());
        List<ImGroupUser> groupUserList = new ArrayList<>();
        for (Long memberId : notExistMemberIdList) {
            ImGroupUser groupUser = new ImGroupUser();
            groupUser.setGroupId(groupId);
            groupUser.setUserId(memberId);
            groupUser.setDelFlag(false);
            groupUserList.add(groupUser);
        }
        this.saveBatch(groupUserList);
    }

    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void removeGroupUser(ImGroupUserDTO groupUserDTO) {
        Long groupId = groupUserDTO.getGroupId();
        ImGroup group = groupService.validateGroup(groupId);
        if (group.getDelFlag()) {
            throw new ServiceException("群组已解散！");
        }

        Long userId = UserUtil.getUserId();
        List<Long> managerIdList = IdSplitUtil.strToList(group.getManager());
        if (group.getMaster().equals(userId)) {
            throw new ServiceException("无移除好友权限！");
        } else {
            if (!managerIdList.contains(userId)) {
                throw new ServiceException("无移除好友权限！");
            }
        }
        List<Long> memberIdList = groupUserDTO.getMemberIdList();
        if (memberIdList.contains(userId)) {
            throw new ServiceException("不能移除自己！");
        }

        LambdaUpdateWrapper<ImGroupUser> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(ImGroupUser::getGroupId, groupId)
                .in(ImGroupUser::getUserId, memberIdList)
                .set(ImGroupUser::getDelFlag, true);
        baseMapper.update(null, updateWrapper);

        // 去除管理员权限
        List<Long> collect = managerIdList.stream().filter(e -> !memberIdList.contains(e)).collect(Collectors.toList());
        LambdaUpdateWrapper<ImGroup> updateWrapper1 = new LambdaUpdateWrapper<>();
        updateWrapper1.eq(ImGroup::getId, groupId)
                .set(ImGroup::getManager, IdSplitUtil.listToStr(collect));
        groupService.update(updateWrapper1);
    }

    @Override
    public List<SysUserVo> listGroupUser(Long id) {
        groupService.validateGroup(id);

        List<SysUserVo> userVoList = new ArrayList<>();
        LambdaQueryWrapper<ImGroupUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ImGroupUser::getGroupId, id)
                .eq(ImGroupUser::getDelFlag, false);
        List<ImGroupUser> groupUserList = baseMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(groupUserList)) {
            return userVoList;
        }

        List<Long> userIdList = groupUserList.stream().map(ImGroupUser::getUserId).collect(Collectors.toList());
        Map<Long, SysUserVo> sysUserVOMap = sysUserService.listByIds(userIdList).stream().map(SysUserVo::fromEntity).collect(Collectors.toMap(SysUserVo::getId, sysUserVo -> sysUserVo));
        for (ImGroupUser groupUser : groupUserList) {
            SysUserVo sysUserVo = sysUserVOMap.get(groupUser.getUserId());
            if (sysUserVo != null) {
                userVoList.add(sysUserVo);
            }
        }
        return userVoList;
    }
}
